/*
 * All rights Reserved, Designed By www.goldbeacon.cn
 * @Title:  demo
 * @Package cn.goldbeacon.demo.common.exception
 * @author: zoujie
 * @date:   2021/8/1114:48
 * @version V1.0
 * Copyright © 2021 www.goldbeacon.cn. All Rights Reserved.
 * 注意：本内容仅限于湖南金烽信息科技有限公司内部传阅，禁止外泄以及用于其他的商业目
 */
package com.chenzhengrong.demospringboot.handler;


import com.chenzhengrong.demospringboot.domain.R;
import com.chenzhengrong.demospringboot.enums.HttpStatusEnum;
import com.chenzhengrong.demospringboot.util.I18nUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 * @author zoujie
 * @title: GlobalExceptionHandler
 * @description: 统一异常处理拦截器
 * @date 2021/8/1114:48
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
    * @description: get请求的参数校验失败
    * @param exception 异常
    * @return cn.goldbeacon.demo.domain.R
    * @author zoujie
    * @date 2021/8/11 19:52
    */
    @ExceptionHandler
    public R handle(ConstraintViolationException exception) {
        log.error("param validation error", exception);
        Set<ConstraintViolation<?>> violations = exception.getConstraintViolations();
        if (!CollectionUtils.isEmpty(violations)) {
            String message = violations.iterator().next().getMessage();
            log.error("validate error,message={0}", message);
            return R.fail(HttpStatusEnum.VALIDATE_ERROR, message);
        }
        return R.fail(HttpStatusEnum.ERROR);
    }

    /**
    * @description: post请求校验失败
    * @param exception 异常
    * @return BaseResponse
    * @author zoujie
    * @date 2021/8/11 15:09
    */
    @ExceptionHandler
    public R handle(MethodArgumentNotValidException exception) {
        log.error("param validation error", exception);
        List<ObjectError> errors = exception.getBindingResult().getAllErrors();
        String msg = HttpStatusEnum.VALIDATE_ERROR.getMsg();
        if (!CollectionUtils.isEmpty(errors)) {
            int first = 0;
            for (int i = 0; i < errors.size(); i++) {
                ObjectError error = errors.get(i);
                String message = error.getDefaultMessage();
                String field = null;
                if (error instanceof FieldError) {
                    field = ((FieldError) error).getField();
                }

                message = I18nUtils.getMessage(message);
                if (i == first) {
                    //取一个错误信息传给前端
                    msg = message;
                }
                log.error("validate error, field={0}, message={1}", field, message);
            }
        }
        return R.fail(HttpStatusEnum.ERROR.getCode(), msg);
    }

    /**
    * @description: 自定义业务异常
    * @param exception 异常
    * @return cn.goldbeacon.demo.domain.R
    * @author zoujie
    * @date 2021/8/11 19:52
    */
    @ExceptionHandler
    public R handle(BusinessException exception) {
        log.error("business error", exception);
        return R.fail(exception.getCode(), exception.getMessage());
    }

    /**
    * @description: 其他没有处理的错误
    * @param exception 异常
    * @return cn.goldbeacon.demo.domain.R<java.lang.Object>
    * @author zoujie
    * @date 2021/8/11 19:53
    */
    @ExceptionHandler
    public R<Object> handle(Exception exception) {
        log.error("unkown error", exception);
        return R.fail(HttpStatusEnum.ERROR);
    }
}
